package zhongbo.java.air.airingestion.listener;

import cn.hutool.core.convert.ConvertException;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import zhongbo.java.air.airingestion.model.FlightPathDao;
import zhongbo.java.air.airingestion.model.enums.SourceType;
import zhongbo.java.air.common.exception.NoStackLogException;

import java.util.Date;
import java.util.UUID;

/*
接收订阅频道log_cannel广播的消息 */
@Component
@Slf4j
//监听redis频道中的消息
public class RedisSubscribeLogChanelListener implements MessageListener {


    private   final RedisTemplate<String ,String> redisTemplate;

    private final RedisLogChanelPublisher redisLogChanelPublisher;

    private final ObjectMapper objectMapper= new ObjectMapper();

    public RedisSubscribeLogChanelListener(RedisLogChanelPublisher redisLogChanelPublisher,RedisTemplate redisTemplate) {
        this.redisLogChanelPublisher = redisLogChanelPublisher;
        this.redisTemplate=redisTemplate;
    }

    @Override
    //pattern匹配模式为订阅模式，message有效
    public void onMessage(Message message, byte[] pattern) {
        //接收到的message对象的字节数组--转字符串
        String msg= new String(message.getBody());

        log.info("收到订阅频道广播发送消息",msg);//记录日志
        System.out.println("收到日志"+msg);//打印消息
        // 转换为DTO对象
        FlightPathDao dto = convert(msg);
        if (dto == null) {
            log.warn("消息解析失败，内容不符合格式: {}", msg);
            return;
        }
        // 转换为JSON字符串并转发
         String processedJson = JSONUtil.toJsonStr(dto);
         redisLogChanelPublisher.Pushlish( processedJson);
         log.info("已处理并转发数据: {}", processedJson);
    }

    public FlightPathDao convert(String msg) {
        // 转换为JSON对象
        JSONObject jsonObject = null;
        try {
            jsonObject = JSONUtil.parseObj(msg);
        } catch (Exception e) {
            throw new NoStackLogException("JSON对象转换失败");
        }
        // 转换为Dto
        FlightPathDao flightPathDto = new FlightPathDao();
        try {
            flightPathDto.setIcaoCode(jsonObject.getStr("icao"));
        } catch (Exception e) {
            throw new NoStackLogException("icao获取失败");
        }

        JSONArray trace = null;
        try {
            // 获取trace
            trace = jsonObject.getJSONArray("trace");

        } catch (Exception e) {
            throw new NoStackLogException("trace获取失败");
        }

        try {
            // 获取时间戳的字符串表示
            String timestampStr = jsonObject.getStr("timestamp");
            // 判断字符串长度
            if (timestampStr.length() == 13) {
                // 如果是13位，直接使用作为毫秒数
                long timeMs = Long.parseLong(timestampStr);
                Date date = new Date(timeMs);
                flightPathDto.setTimestamp(date);
            } else {
                // 如果不是13位，乘以1000转换为毫秒数
                double timestamp = jsonObject.getDouble("timestamp") + trace.get(0, Long.class);
                long timeMs = (long)(timestamp * 1000);
                flightPathDto.setTimestamp(new Date(timeMs));
            }
        } catch (Exception e) {
            throw new NoStackLogException("timestamp获取失败");
        }
        // 获取纬度
        try {
            flightPathDto.setLatitude(trace.get(1, Double.class));
        } catch (Exception e) {
            throw new NoStackLogException("latitude获取失败");
        }
        // 获取经度
        try {
            flightPathDto.setLongitude(trace.get(2, Double.class));
        } catch (ConvertException e) {
            throw new NoStackLogException("longitude获取失败");
        }
        // 获取海拔高度
        try {
            String strAltitude = trace.get(3, String.class);
            if ("ground".equals(strAltitude)){
                flightPathDto.setAltitude(0.0);
            }else {
                flightPathDto.setAltitude(Double.parseDouble(strAltitude));
            }
        } catch (ConvertException e) {
            throw new NoStackLogException("altitude获取失败");
        }
        // 获取地速
        try {
            flightPathDto.setSpeed(trace.get(4, Double.class));
        } catch (ConvertException e) {
            throw new NoStackLogException("speed获取失败");
        }
        // 获取方向角
        try {
            flightPathDto.setHeading(trace.get(5, Double.class));
        } catch (ConvertException e) {
            throw new NoStackLogException("heading获取失败");
        }
        // 获取source_type
        try {
            JSONObject object = trace.get(8, JSONObject.class);
            // 做一个非空判断
            if (object != null) {
                flightPathDto.setSourceType(object.get("type", String.class));
            }
        } catch (ConvertException e) {
            throw new NoStackLogException("sourceType获取失败");
        }
        return flightPathDto;
    }

}
